﻿using System.Threading.Tasks;
using Xproject.Framework.Core;
using Xproject.Framework.Core.DataContext;
using Xproject.Framework.Core.Repositories;
using Model.WXshopBuiness;
using Repository.WXshopBuiness;
using Xproject.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Model.Const;
using Model.Util;
using Repository.Util;
using Model.Util.Enum;
using Model.ZXBuiness;
using Repository.ZXBuiness;
namespace Services.WXshopBuiness
{
    public class WXProductServices : Service
    {
        IRepositoryAsync<WXProduct> m_WXProductRepository;
        IRepositoryAsync<Category> m_CategoryRepository;
        IRepositoryAsync<ProductContents> m_ProductContentsRepository;
        IRepositoryAsync<UploadFile> m_UploadFileRepository;
        IRepositoryAsync<ProductComments> m_ProductCommentsRepository;
        IRepositoryAsync<WeiXinProductAttr> m_productAttrRepository;
        IRepositoryAsync<Identity> m_IdentityRepository;
        IRepositoryAsync<ProductSpecification> m_ProductSpecificationRepository;
        IRepositoryAsync<ZXProductRate> m_ZXProductRateRepository;
        public WXProductServices(IDataContextAsync dataContext) : base(dataContext)
        {
            m_WXProductRepository = m_UnitOfWork.RepositoryAsync<WXProduct>();
            m_CategoryRepository = m_UnitOfWork.RepositoryAsync<Category>();
            m_ProductContentsRepository = m_UnitOfWork.RepositoryAsync<ProductContents>();
            m_UploadFileRepository = m_UnitOfWork.RepositoryAsync<UploadFile>();
            m_ProductCommentsRepository = m_UnitOfWork.RepositoryAsync<ProductComments>();
            m_productAttrRepository = m_UnitOfWork.RepositoryAsync<WeiXinProductAttr>();
            m_IdentityRepository = m_UnitOfWork.RepositoryAsync<Identity>();
            m_ProductSpecificationRepository = m_UnitOfWork.RepositoryAsync<ProductSpecification>();
            m_ZXProductRateRepository = m_UnitOfWork.RepositoryAsync<ZXProductRate>();
        }


        public bool InsertProductRate(ZXProductRate rate)
        {
            rate.EntityState = EntityState.Added;
            m_ZXProductRateRepository.Insert(rate);
            return m_UnitOfWork.SaveChanges() == 1;
        }

        public bool EditProductRate(ZXProductRate rate)
        {
            rate.EntityState = EntityState.Modified;
            m_ZXProductRateRepository.Update(rate);
            return m_UnitOfWork.SaveChanges() == 1;
        }


        public ZXProductRate GetProductRate(string productId)
        {
            return m_ZXProductRateRepository.GetByproductId(productId);
        }

        public List<ProductSpecification> GetProductSpecList(string productId)
        {
            return m_ProductSpecificationRepository.GetProdAllSpecifations(productId);
        }

        public ProductSpecification GetProductSpecification(string specifationId)
        {
            return m_ProductSpecificationRepository.GetProdSpecifation(specifationId); 
        }

        public bool AddWXProduct(WXProduct product, List<UploadFile> ufs, List<ProductContents> productContents, string userId)
        {
            if (product != null)
            {
                if (string.IsNullOrEmpty(product.ProductID))
                {
                    product.ProductID = Guid.NewGuid().ToString();
                }
                product.EntityState = EntityState.Added;
                product.CreateTime = DateTime.Now;
                product.UpdateTime = DateTime.Now;
                product.Creator = product.Updator = userId.ToString();
                m_UnitOfWork.BeginTransaction();
                if (ufs.Count > 0)
                {
                    foreach (UploadFile uf in ufs)
                    {
                        uf.EntityState = EntityState.Added;
                        uf.CreateTime = DateTime.Now;
                        uf.Creator = userId.ToString();
                    }
                    m_UploadFileRepository.InsertRange(ufs);

                }
                if (productContents.Count > 0)
                {
                    foreach (ProductContents pc in productContents)
                    {
                        pc.EntityState = EntityState.Added;
                    }
                    m_ProductContentsRepository.InsertRange(productContents);
                }
                m_WXProductRepository.Insert(product);

                if (m_UnitOfWork.SaveChanges() == productContents.Count + 1 + ufs.Count)
                {
                    m_UnitOfWork.Commit();
                    return true;
                }
                else
                {
                    m_UnitOfWork.Rollback();
                    return false;
                }
            }
            return false;
        }

        public bool AddProductComments(ProductComments comments,UploadFile uf,string userId)
        {
            m_UnitOfWork.BeginTransaction();
            int result = 0;
            if (uf != null)
            {
                uf.EntityState = EntityState.Added;
                uf.CreateTime = DateTime.Now;
                uf.Creator = userId;
                m_UploadFileRepository.Insert(uf);
                result++;
            }
            if (comments != null)
            {
                comments.ID = Guid.NewGuid().ToString();
                comments.EntityState = EntityState.Added;
                m_ProductCommentsRepository.Insert(comments);
                result++;
               
            }
            if (m_UnitOfWork.SaveChanges() == result)
            {
                m_UnitOfWork.Commit();
                return true;
            }
            else
            {
                m_UnitOfWork.Rollback();                
                LogHelper.WriteInfoLog("新增用户评论失败 productID :" +comments.ProductID);
                return false;
            }
           
        }

        public string CreateProductCode(string pre,string productId)
        {
            Identity iden = new Identity();
            iden.CreateTime = DateTime.Now;
            iden.EntityState = EntityState.Added;
            iden.ProjectID = productId;
            iden.Guid = Guid.NewGuid().ToString();
            m_IdentityRepository.Insert(iden);
            m_UnitOfWork.SaveChanges();
            Identity nid = m_IdentityRepository.Get(iden.Guid);
            string times = DateTime.Now.ToString("yyyyMMddHHmmss");
            return  pre+times+ nid.ID.ToString();
        }

        public bool DelWXProductComment(ProductComments productcomments)
        {
            if (productcomments != null)
            {
                productcomments.EntityState = EntityState.Deleted;
                m_ProductCommentsRepository.Delete(productcomments);
                return m_UnitOfWork.SaveChanges() == 1;
            }
            return false;
        }

        public bool DelProductSpec(ProductSpecification spec)
        {
            if (spec != null)
            {
                spec.EntityState = EntityState.Deleted;
                m_ProductSpecificationRepository.Delete(spec);
                return m_UnitOfWork.SaveChanges() == 1;
            }
            return false;
        }


        /// <summary>
        /// 删除最好不做硬删除  做软删除
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        public bool DelWXProduct(WXProduct product)
        {
            if (product != null)
            {
                product.EntityState = EntityState.Deleted;
                m_WXProductRepository.Delete(product);
                return m_UnitOfWork.SaveChanges() == 1;
            }
            return false;
        }

        public bool UpdateWXProduct(WXProduct product)
        {
            product.EntityState = EntityState.Modified;
            product.UpdateTime = DateTime.Now;
            m_WXProductRepository.Update(product);
            return m_UnitOfWork.SaveChanges() == 1;
        }

        public bool EditWXProduct(WXProduct product, List<UploadFile> ufs, List<ProductContents> addproductContents, List<ProductContents> editproductContents, string userId)
        {
            if (product != null)
            {
                product.EntityState = EntityState.Modified;
                product.UpdateTime = DateTime.Now;
                product.Updator = userId.ToString();
                m_WXProductRepository.Update(product);
                m_UnitOfWork.BeginTransaction();
                if (ufs.Count > 0)
                {
                    foreach (UploadFile uf in ufs)
                    {
                        uf.EntityState = EntityState.Added;
                        uf.CreateTime = DateTime.Now;
                        uf.Creator = userId.ToString();
                    }
                    m_UploadFileRepository.InsertRange(ufs);

                }
                if (addproductContents.Count > 0)
                {
                    foreach (ProductContents pc in addproductContents)
                    {
                        pc.EntityState = EntityState.Added;
                    }
                    m_ProductContentsRepository.InsertRange(addproductContents);
                }
                if (editproductContents.Count > 0)
                {
                    foreach (ProductContents pc in editproductContents)
                    {
                        pc.EntityState = EntityState.Modified;
                    }
                    m_ProductContentsRepository.UpdateRange(editproductContents);
                }
                int result = m_UnitOfWork.SaveChanges();
                if (result == (addproductContents.Count + editproductContents .Count+ 1 + ufs.Count))
                {
                    m_UnitOfWork.Commit();
                    return true;
                }
                else
                {
                    m_UnitOfWork.Rollback();
                    return false;
                }
            }
            return false;
        }

        public bool EditProductComments(ProductComments productComments,UploadFile uf,string userId)
        {
            m_UnitOfWork.BeginTransaction();
            int result = 0;
            if (uf != null)
            {
                uf.EntityState = EntityState.Added;
                uf.CreateTime = DateTime.Now;
                uf.Creator = userId;
                m_UploadFileRepository.Insert(uf);
                result++;
            }
            if (productComments != null)
            {
                productComments.EntityState = EntityState.Modified;
                m_ProductCommentsRepository.Update(productComments);
                result++;
              
            }
            if (m_UnitOfWork.SaveChanges() == result)
            {
                m_UnitOfWork.Commit();
                return true;
            }
            else
            {
                m_UnitOfWork.Rollback();
                LogHelper.WriteInfoLog("编辑用户用户评论失败 productID :" + productComments.ProductID);
                return false;
            }             

        }

        public ProductSpecification GetProdSpecById(string SpecifactionId)
        {
            return m_ProductSpecificationRepository.GetProdSpecifation(SpecifactionId);
        }
        public bool AddProductSpecifation(ProductSpecification specification)
        {
            specification.EntityState = EntityState.Added;
            m_ProductSpecificationRepository.Insert(specification);
            return m_UnitOfWork.SaveChanges() == 1;
        }

        public bool EditProductSpecifation(ProductSpecification specification)
        {
            specification.EntityState = EntityState.Modified;
            m_ProductSpecificationRepository.Update(specification);
            return m_UnitOfWork.SaveChanges() == 1;
        }
        public WXProduct GetById(string productId)
        {
            return m_WXProductRepository.Get(productId);
        }

        public WXProduct GetByProductCode(string productCode)
        {
            return m_WXProductRepository.GetByProductCode(productCode);
        }

        public ProductComments GetCommentById(string ID)
        {
            return m_ProductCommentsRepository.GetById(ID);
        }

        public ProductComments GetMyComments(string orderId,string productId, string userId)
        {
            return m_ProductCommentsRepository.GetMyComments(orderId,productId, userId);
        }

        private List<WXProduct> GetALLWXProduct(string site)
        {
            if (Cache_Product.WXProduct == null)
            {
                Cache_Product.WXProduct = m_WXProductRepository.GetAllWXProducts(site);
            }
            return Cache_Product.WXProduct;
        }


        public List<WXProduct> GetAllWXProducts(string site, int offset, int limit, string productName, string productCode, string productDesc, string key,
            int? isSheepFree, string remarks, int? state, int? categoryID, DateTime? startTime, DateTime? endTime, string order, string ordername, out int total)
        {
            List<WXProduct> allProducts = GetALLWXProduct(site);

            if (!string.IsNullOrEmpty(productName))
            {
                allProducts = allProducts.Where(i => i.ProductName.Contains(productName)).ToList();
            }
            if (!string.IsNullOrEmpty(productCode))
            {
                allProducts = allProducts.Where(i => i.ProductCode.Contains(productCode)).ToList(); ;
            }
            if (!string.IsNullOrEmpty(productDesc))
            {
                allProducts = allProducts.Where(i => i.ShortDesc.Contains(productDesc)).ToList(); ;
            }
            if (!string.IsNullOrEmpty(key))
            {
                allProducts = allProducts.Where(i => i.ProductKeyword.Contains(key)).ToList(); ;
            }
            if (isSheepFree.HasValue)
            {
                allProducts = allProducts.Where(i => i.IsFreeShipping == isSheepFree.Value).ToList(); ;
            }
            if (state.HasValue)
            {
                allProducts = allProducts.Where(i => i.State == state.Value).ToList();
            }
            if (categoryID.HasValue)
            {
                allProducts = allProducts.Where(i => i.CategoryID == categoryID).ToList();
            }
            if (!string.IsNullOrEmpty(remarks))
            {
                allProducts = allProducts.Where(i => i.Remark.Contains(remarks)).ToList();
            }

            if (startTime.HasValue)
            {
                allProducts = allProducts.Where(i => i.CreateTime >= startTime.Value).ToList();
            }
            if (endTime.HasValue)
            {
                allProducts = allProducts.Where(i => i.CreateTime <= endTime.Value).ToList();
            }
            //List <WXProduct> temp = m_WXProductRepository.GetAllWXProducts(site,productName,productCode,productDesc,key,isSheepFree,remarks,state,
            //    startTime,endTime,order,ordername);
            total = allProducts.Count;
            return allProducts.Skip(offset).Take(limit).ToList();
        }


        public List<ProductComments> GetAllProductComments(string site, int offset, int limit, string productName, string productCode, DateTime? startTime, DateTime? endTime, string order, string ordername, out int total)
        {
            total = 0;
            List<ProductComments> list = m_ProductCommentsRepository.GetCommentsList(productName, productCode, startTime, endTime, order, ordername);
            total = list.Count;
            return list.Skip(offset).Take(limit).ToList();
        }

        public List<WeiXinProductAttr> GetProductAttrs(string productId)
        {
            return m_productAttrRepository.GetProductAttrs(productId);
        }
        public bool EditProductAttr(List<WeiXinProductAttr> newAttrs,string productId)
        {
            m_UnitOfWork.BeginTransaction();
            int delcount = 0;
            int addcount = 0;
            List<WeiXinProductAttr> oldAttrs = m_productAttrRepository.GetProductAttrs(productId);
            if (oldAttrs != null && oldAttrs.Count > 0)
            {
                foreach (WeiXinProductAttr at in oldAttrs)
                {
                    at.EntityState = EntityState.Deleted;
                }
                //先删除原有的属性
                m_productAttrRepository.DeleteRange(oldAttrs);
                delcount = oldAttrs.Count;
            }
            if (newAttrs != null && newAttrs.Count > 0)
            {
                foreach (WeiXinProductAttr at in newAttrs)
                {
                    at.ID = Guid.NewGuid().ToString();
                    at.EntityState = EntityState.Added;
                }
                m_productAttrRepository.InsertRange(newAttrs);
                addcount = newAttrs.Count;
            }
            if ((delcount + addcount) == m_UnitOfWork.SaveChanges())
            {
                m_UnitOfWork.Commit();
                return true;
            }
            else
            {
                m_UnitOfWork.Rollback();
                return false;
            }

        }

        #region 前端用
        /// <summary>
        /// 前端使用 获取商品的属性
        /// </summary>
        /// <param name="productId"></param>
        /// <returns></returns>
        public List<WeiXinProductAttrShowModel> GetProductAttrsF(string productId)
        {
            return m_productAttrRepository.GetProductAttrsF(productId);
        }

        /// <summary>
        /// 默认快递费
        /// </summary>
        /// <param name="productId"></param>
        /// <returns></returns>
        public WeiXinProductAttrShowModel GetProductDefaultKDF(string productId)
        {
            return m_productAttrRepository.GetProductAttrsByCategoryType(productId, (int)Enum_CategoryType.默认快递费);
        }

        public List<ProductComments> GetTopNComments(string site, string productId, int TopN)
        {
            List<ProductComments> list =m_ProductCommentsRepository.GetProductComments(productId);
            if (list != null) {
                return list.Take(TopN).ToList();
            }
            return null;

        }

        public bool InsertProductComments(ProductComments productcomments)
        {
            productcomments.EntityState = EntityState.Added;
            m_ProductCommentsRepository.Insert(productcomments);
            return m_UnitOfWork.SaveChanges() == 1;
        }


        public List<ProductContents> GetProductContent(string productId)
        {
            return m_ProductContentsRepository.GetProductContents(productId);
        }

        /// <summary>
        /// 得到前N个推荐的产品
        /// </summary>
        /// <param name="site"></param>
        /// <param name="topN"></param>
        /// <returns></returns>
        public List<WXProduct> GetWXProductTuiJian(string site, int topN)
        {
            List<WXProduct> allList = GetALLWXProduct(site);
            if (Cache_Product.WXProductTuiJian == null)
            {
                Cache_Product.WXProductTuiJian = allList.Where(i => i.ShowOnWhere == SystemConst.DashBoard_Position_TuiJian).OrderByDescending(i => i.SortID).Take(topN).ToList();
            }
            return Cache_Product.WXProductTuiJian;
        }

        public List<WXProduct> GetWXProductIndex(string site, int? limit, int? offset)
        {
            List<WXProduct> allList = GetALLWXProduct(site);
            allList = allList.Where(i => i.State == 0).ToList();
            return allList.Skip((offset.Value-1)*limit.Value).Take(limit.Value).ToList();
        }

        public List<WXProduct> GetCategoryWXProduct(string site,int cateId, int? limit, int? offset)
        {
            List<WXProduct> allProducts = GetALLWXProduct(site);
            allProducts =  allProducts.Where(i => i.CategoryID == cateId).ToList();
            return allProducts.Skip((offset.Value - 1) * limit.Value).Take(limit.Value).ToList();
        }

       
        #endregion
    }
}
